home *** CD-ROM | disk | FTP | other *** search
- /*
- HLE bios emulation
- ==================
-
- Written by BERO
- */
-
- #include "fpse.h"
-
- #define PSADDR2(addr,base) ((int)addr-(int)base)
- #define PSADDR(addr,base) (int)(addr?PSADDR2(addr,base):(int)addr)
- #define PCADDR(addr,base) (addr?(addr+base):(void*)addr)
-
- static int bios_a0();
- static int bios_b0();
- static int bios_c0();
-
- static char *a0name[] = {
- /* 0x00 */ "open",
- /* 0x01 */ "lseek",
- /* 0x02 */ "read",
- /* 0x03 */ "write",
- /* 0x04 */ "close",
- /* 0x05 */ "ioctl",
- /* 0x06 */ "exit",
- /* 0x07 */ "bios_a0_07",
- /* 0x08 */ "getc",
- /* 0x09 */ "putc",
- /* 0x0a */ "todigit",
- /* 0x0b */ "atof",
- /* 0x0c */ "strtoul",
- /* 0x0d */ "strtol",
- /* 0x0e */ "abs",
- /* 0x0f */ "labs",
- /* 0x10 */ "atoi",
- /* 0x11 */ "atol",
- /* 0x12 */ "atob",
- /* 0x13 */ "setjmp",
- /* 0x14 */ "longjmp",
- /* 0x15 */ "strcat",
- /* 0x16 */ "strncat",
- /* 0x17 */ "strcmp",
- /* 0x18 */ "strncmp",
- /* 0x19 */ "strcpy",
- /* 0x1a */ "strnpy",
- /* 0x1b */ "strlen",
- /* 0x1c */ "index",
- /* 0x1d */ "rindex",
- /* 0x1e */ "strchr",
- /* 0x1f */ "strrchr",
- /* 0x20 */ "strpbrk",
- /* 0x21 */ "strspn",
- /* 0x22 */ "strcspn",
- /* 0x23 */ "strtok",
- /* 0x24 */ "strstr",
- /* 0x25 */ "toupper",
- /* 0x26 */ "tolower",
- /* 0x27 */ "bcopy",
- /* 0x28 */ "bzero",
- /* 0x29 */ "bcmp",
- /* 0x2a */ "memcpy",
- /* 0x2b */ "memset",
- /* 0x2c */ "memmove",
- /* 0x2d */ "memcmp",
- /* 0x2e */ "memchr",
- /* 0x2f */ "rand",
- /* 0x30 */ "srand",
- /* 0x31 */ "qsort",
- /* 0x32 */ "strtod",
- /* 0x33 */ "malloc",
- /* 0x34 */ "free",
- /* 0x35 */ "lsearch",
- /* 0x36 */ "bsearch",
- /* 0x37 */ "calloc",
- /* 0x38 */ "realloc",
- /* 0x39 */ "InitHeap",
- /* 0x3a */ "_exit",
- /* 0x3b */ "getchar",
- /* 0x3c */ "putchar",
- /* 0x3d */ "gets",
- /* 0x3e */ "puts",
- /* 0x3f */ "printf",
- /* 0x40 */ "bios_a0_40",
- /* 0x41 */ "LoadTest",
- /* 0x42 */ "Load",
- /* 0x43 */ "Exec",
- /* 0x44 */ "FlushCache",
- /* 0x45 */ "InstallInterruptHandler",
- /* 0x46 */ "GPU_dw",
- /* 0x47 */ "mem2vram",
- /* 0x48 */ "SendGPU",
- /* 0x49 */ "GPU_cw",
- /* 0x4a */ "GPU_cwb",
- /* 0x4b */ "SendPackets",
- /* 0x4c */ "bios_a0_4c",
- /* 0x4d */ "GetGPUStatus",
- /* 0x4e */ "GPU_sync",
- /* 0x4f */ "bios_a0_4f",
- /* 0x50 */ "bios_a0_50",
- /* 0x51 */ "LoadExec",
- /* 0x52 */ "GetSysSp",
- /* 0x53 */ "bios_a0_53",
- /* 0x54 */ "_96_init",
- /* 0x55 */ "_bu_init",
- /* 0x56 */ "_96_remove",
- /* 0x57 */ "bios_a0_57",
- /* 0x58 */ "bios_a0_58",
- /* 0x59 */ "bios_a0_59",
- /* 0x5a */ "bios_a0_5a",
- /* 0x5b */ "dev_tty_init",
- /* 0x5c */ "dev_tty_open",
- /* 0x5d */ "dev_tty_5d",
- /* 0x5e */ "dev_tty_ioctl",
- /* 0x5f */ "dev_cd_open",
- /* 0x60 */ "dev_cd_read",
- /* 0x61 */ "dev_cd_close",
- /* 0x62 */ "dev_cd_firstfile",
- /* 0x63 */ "dev_cd_nextfile",
- /* 0x64 */ "dev_cd_chdir",
- /* 0x65 */ "dev_card_open",
- /* 0x66 */ "dev_card_read",
- /* 0x67 */ "dev_card_write",
- /* 0x68 */ "dev_card_close",
- /* 0x69 */ "dev_card_firstfile",
- /* 0x6a */ "dev_card_nextfile",
- /* 0x6b */ "dev_card_erase",
- /* 0x6c */ "dev_card_undelete",
- /* 0x6d */ "dev_card_format",
- /* 0x6e */ "dev_card_rename",
- /* 0x6f */ "dev_card_6f",
- /* 0x70 */ "_bu_init(a0_70)",
- /* 0x71 */ "_96_init(a0_71)",
- /* 0x72 */ "_96_remove(a0_72)",
- /* 0x73 */ "bios_a0_73",
- /* 0x74 */ "bios_a0_74",
- /* 0x75 */ "bios_a0_75",
- /* 0x76 */ "bios_a0_76",
- /* 0x77 */ "bios_a0_77",
- /* 0x78 */ "_96_CdSeekL",
- /* 0x79 */ "bios_a0_79",
- /* 0x7a */ "bios_a0_7a",
- /* 0x7b */ "bios_a0_7b",
- /* 0x7c */ "_96_CdGetStatus",
- /* 0x7d */ "bios_a0_7d",
- /* 0x7e */ "_96_CdRead",
- /* 0x7f */ "bios_a0_7f",
- /* 0x80 */ "bios_a0_80",
- /* 0x81 */ "bios_a0_81",
- /* 0x82 */ "bios_a0_82",
- /* 0x83 */ "bios_a0_83",
- /* 0x84 */ "bios_a0_84",
- /* 0x85 */ "_96_CdStop",
- /* 0x86 */ "bios_a0_86",
- /* 0x87 */ "bios_a0_87",
- /* 0x88 */ "bios_a0_88",
- /* 0x89 */ "bios_a0_89",
- /* 0x8a */ "bios_a0_8a",
- /* 0x8b */ "bios_a0_8b",
- /* 0x8c */ "bios_a0_8c",
- /* 0x8d */ "bios_a0_8d",
- /* 0x8e */ "bios_a0_8e",
- /* 0x8f */ "bios_a0_8f",
- /* 0x90 */ "bios_a0_90",
- /* 0x91 */ "bios_a0_91",
- /* 0x92 */ "bios_a0_92",
- /* 0x93 */ "bios_a0_93",
- /* 0x94 */ "bios_a0_94",
- /* 0x95 */ "bios_a0_95",
- /* 0x96 */ "AddCDROMDevice",
- /* 0x97 */ "AddMemCardDevice",
- /* 0x98 */ "DisableKernelIORedirection",
- /* 0x99 */ "EnableKernelIORedirection",
- /* 0x9a */ "bios_a0_9a",
- /* 0x9b */ "bios_a0_9b",
- /* 0x9c */ "SetConf # may be",
- /* 0x9d */ "GetConf # ",
- /* 0x9e */ "bios_a0_9e",
- /* 0x9f */ "SetMem",
- /* 0xa0 */ "_boot",
- /* 0xa1 */ "SystemError",
- /* 0xa2 */ "EnqueueCdIntr",
- /* 0xa3 */ "DequeueCdIntr",
- /* 0xa4 */ "bios_a0_a4",
- /* 0xa5 */ "ReadSector",
- /* 0xa6 */ "get_cd_status",
- /* 0xa7 */ "bufs_cb_0",
- /* 0xa8 */ "bufs_cb_1",
- /* 0xa9 */ "bufs_cb_2",
- /* 0xaa */ "bufs_cb_3",
- /* 0xab */ "_card_info",
- /* 0xac */ "_card_load",
- /* 0xad */ "_card_auto",
- /* 0xae */ "bufs_cb_4",
- /* 0xaf */ "bios_a0_af",
- /* 0xb0 */ "bios_a0_b0",
- /* 0xb1 */ "bios_a0_b1",
- /* 0xb2 */ "do_a_long_jmp",
- /* 0xb3 */ "bios_a0_b3",
- /* 0xb4 */ "bios_a0_b4"
- };
-
- static char *b0name[] = {
- /* 0x00 */ "SysMalloc",
- /* 0x01 */ "bios_b0_01",
- /* 0x02 */ "bios_b0_02",
- /* 0x03 */ "bios_b0_03",
- /* 0x04 */ "bios_b0_04",
- /* 0x05 */ "bios_b0_05",
- /* 0x06 */ "bios_b0_06",
- /* 0x07 */ "DeliverEvent",
- /* 0x08 */ "OpenEvent",
- /* 0x09 */ "CloseEvent",
- /* 0x0a */ "WaitEvent",
- /* 0x0b */ "TestEvent",
- /* 0x0c */ "EnableEvent",
- /* 0x0d */ "DisableEvent",
- /* 0x0e */ "OpenTh",
- /* 0x0f */ "CloseTh",
- /* 0x10 */ "ChangeTh",
- /* 0x11 */ "bios_b0_11",
- /* 0x12 */ "InitPAD",
- /* 0x13 */ "StartPAD",
- /* 0x14 */ "StopPAD",
- /* 0x15 */ "PAD_init",
- /* 0x16 */ "PAD_dr",
- /* 0x17 */ "ReturnFromException",
- /* 0x18 */ "ResetEntryInt",
- /* 0x19 */ "HookEntryInt",
- /* 0x1a */ "bios_b0_1a",
- /* 0x1b */ "bios_b0_1b",
- /* 0x1c */ "bios_b0_1c",
- /* 0x1d */ "bios_b0_1d",
- /* 0x1e */ "bios_b0_1e",
- /* 0x1f */ "bios_b0_1f",
- /* 0x20 */ "UnDeliverEvent",
- /* 0x21 */ "bios_b0_21",
- /* 0x22 */ "bios_b0_22",
- /* 0x23 */ "bios_b0_23",
- /* 0x24 */ "bios_b0_24",
- /* 0x25 */ "bios_b0_25",
- /* 0x26 */ "bios_b0_26",
- /* 0x27 */ "bios_b0_27",
- /* 0x28 */ "bios_b0_28",
- /* 0x29 */ "bios_b0_29",
- /* 0x2a */ "bios_b0_2a",
- /* 0x2b */ "bios_b0_2b",
- /* 0x2c */ "bios_b0_2c",
- /* 0x2d */ "bios_b0_2d",
- /* 0x2e */ "bios_b0_2e",
- /* 0x2f */ "bios_b0_2f",
- /* 0x30 */ "bios_b0_30",
- /* 0x31 */ "bios_b0_31",
- /* 0x32 */ "open(b0)",
- /* 0x33 */ "lseek(b0)",
- /* 0x34 */ "read(b0)",
- /* 0x35 */ "write(b0)",
- /* 0x36 */ "close(b0)",
- /* 0x37 */ "ioctl(b0)",
- /* 0x38 */ "exit(b0)",
- /* 0x39 */ "bios_b0_39",
- /* 0x3a */ "getc(b0)",
- /* 0x3b */ "putc(b0)",
- /* 0x3c */ "getchar(b0)",
- /* 0x3d */ "putchar(b0)",
- /* 0x3e */ "gets(b0)",
- /* 0x3f */ "puts(b0)",
- /* 0x40 */ "cd",
- /* 0x41 */ "format",
- /* 0x42 */ "firstfile",
- /* 0x43 */ "nextfile",
- /* 0x44 */ "rename",
- /* 0x45 */ "delete",
- /* 0x46 */ "undelete",
- /* 0x47 */ "AddDevice",
- /* 0x48 */ "RemoteDevice",
- /* 0x49 */ "PrintInstalledDevices",
- /* 0x4a */ "InitCARD",
- /* 0x4b */ "StartCARD",
- /* 0x4c */ "StopCARD",
- /* 0x4d */ "bios_b0_4d",
- /* 0x4e */ "_card_write",
- /* 0x4f */ "_card_read",
- /* 0x50 */ "_new_card",
- /* 0x51 */ "Krom2RawAdd",
- /* 0x52 */ "bios_b0_52",
- /* 0x53 */ "bios_b0_53",
- /* 0x54 */ "_get_errno",
- /* 0x55 */ "_get_error",
- /* 0x56 */ "GetC0Table",
- /* 0x57 */ "GetB0Table",
- /* 0x58 */ "_card_chan",
- /* 0x59 */ "bios_b0_59",
- /* 0x5a */ "bios_b0_5a",
- /* 0x5b */ "ChangeClearPAD",
- /* 0x5c */ "_card_status",
- /* 0x5d */ "_card_wait"
- };
-
- static char *c0name[]={
- /* 0x00 */ "InitRCnt",
- /* 0x01 */ "InitException",
- /* 0x02 */ "SysEnqIntRP",
- /* 0x03 */ "SysDeqIntRP",
- /* 0x04 */ "get_free_EvCB_slot",
- /* 0x05 */ "get_free_TCB_slot",
- /* 0x06 */ "ExceptionHandler",
- /* 0x07 */ "InstallExceptionHandler",
- /* 0x08 */ "SysInitMemory",
- /* 0x09 */ "SysInitKMem",
- /* 0x0a */ "ChangeClearRCnt",
- /* 0x0b */ "SystemError(c0)",
- /* 0x0c */ "InitDefInt",
- /* 0x0d */ "bios_c0_0d",
- /* 0x0e */ "bios_c0_0e",
- /* 0x0f */ "bios_c0_0f",
- /* 0x10 */ "bios_c0_10",
- /* 0x11 */ "bios_c0_11",
- /* 0x12 */ "InstallDevices",
- /* 0x13 */ "FlushStdInOutPut",
- /* 0x14 */ "bios_c0_14",
- /* 0x15 */ "_cdevinput",
- /* 0x16 */ "_cdevscan",
- /* 0x17 */ "_circgetc",
- /* 0x18 */ "_circputc",
- /* 0x19 */ "ioabort",
- /* 0x1a */ "bios_c0_1a",
- /* 0x1b */ "KernelRedirect",
- /* 0x1c */ "PatchAOTable",
- };
-
- static void *realaddr(int addr) { return (char*)baseaddr(addr)+addr; }
-
- #define v0 reg.r[2]
- #define v1 reg.r[3]
- #define a0 reg.r[4]
- #define a1 reg.r[5]
- #define a2 reg.r[6]
- #define a3 reg.r[7]
- #define sp reg.r[29]
- #define stack ((int*)realaddr(reg.r[29]))
-
- int biosprint(int pc)
- {
- int ret = 0;
- int no = reg.r[9];
-
- if (verbose) {
- char *name = NULL;
- switch(pc){
- case 0xa0:
- if (no<sizeof(a0name)/sizeof(a0name[0]))
- name = a0name[no];
- break;
- case 0xb0:
- if (no<sizeof(b0name)/sizeof(b0name[0]))
- name = b0name[no];
- break;
- case 0xc0:
- if (no<sizeof(c0name)/sizeof(c0name[0]))
- name = c0name[no];
- break;
- }
- if (name) {
- printf("bios:%s ",name);
- } else {
- printf("bios:%02x,%x",(int)pc,(int)no);
- }
- }
-
- if (!emulate_bios) {
- switch(pc) {
- case 0xa0:
- switch(no) {
- case 0x3f: // printf
- PRINTF("%s",(char *)realaddr(a0)); break;
- }
- break;
- case 0xb0:
- switch(no) {
- case 0x08: // OpenEvent
- PRINTF("(%x,%x,%x,%x)",(int)a0,(int)a1,(int)a2,(int)a3);
- break;
- case 0x09: //
- case 0x0C: //
- case 0x0D: //
- PRINTF("(%x)",(int)a0); break;
- case 0x3c: // getchar
- v0 = getchar(); PC = reg.r[31]; break;
- case 0x3e: // gets
- {
- char *base = (char*)baseaddr(a0);
- char *ret = gets(base + a0);
- v0 = PSADDR(ret,base);
- PC = reg.r[31];
- }
- break;
- case 0x3f: // puts
- v0 = puts(realaddr(a0)); PC = reg.r[31]; break;
- case 0x3d: // putchar
- putchar(a0); PC = reg.r[31]; break;
- }
- }
- } else {
- switch (pc) {
- case 0xa0: ret = bios_a0(); break;
- case 0xb0: ret = bios_b0(); break;
- case 0xc0: ret = bios_c0(); break;
- }
- if ((pc!=0xb0) || (no!=0x17)) // ReturnFromException
- PC = reg.r[31];
- }
-
- PRINTF("\n");
- return ret;
- }
-
- static char *qbase;
- static int qsub;
-
- static int save_reg[32+3];
- static int *jmpbuf;
-
- static char *heapbase;
-
- static int qcmp(const void *arg0,const void *arg1)
- {
- a0 = PSADDR2(arg0,qbase);
- a1 = PSADDR2(arg1,qbase);
- /* qsubðÀs */
- return v0;
- }
-
- typedef struct {
- char id[6];
- char fontname[8];
- UINT8 w,h;
- UINT8 type;
- UINT8 ntbl;
- UINT16 codetbl[1];
- } FONTXHDR;
-
- static FONTXHDR *font;
-
- /*
- FONTX format
- idx siz
- 0 6 "FONTX"
- 6 8 font name
- 14 1 width
- 15 1 height
- 16 1 type 0=ANK,1=Japanese
- ANK:
- 17 font data
- Japanese:
- 17 1 Number of code table
- 18 2 start of code (little endian)
- 19 2 end of code
- .
- .
- 18+N*4 font data
- */
- void *Krom2RawAdd(int code)
- {
- UINT16 *ptbl = font->codetbl;
- int size = ((font->w+7)/8)*font->h;
- int n=0,i;
-
- for(i=0;i<font->ntbl;i++) {
- if (code>=ptbl[0] && code<=ptbl[1]) {
- return (char*)&font->codetbl[font->ntbl*2] +
- (code-ptbl[0]+n)*size+2; /* skip */
- }
- n += ptbl[1]-ptbl[0] + 1;
- ptbl+=2;
- }
- return NULL;
- }
-
- #define strcmpz(a,b) memcmp(a,b,strlen(b))
-
- static char *cd_path="e:";
- static char *bu00_path="bu00\\";
- static char *bu10_path="bu10\\";
- static char *pcdrv_path="";
-
- static char *real_path(char *name)
- {
- static char buf[256];
-
- if (strcmpz(name,"cdrom:")==0) {
- strcpy(buf,cd_path);
- strcat(buf,name+6);
- {
- char *p = buf+strlen(buf);
- p[-2]='\0';
- /* "cdrom:filename;1" */
- }
- } else if (strcmpz(name,"bu00:")==0) {
- strcpy(buf,bu00_path);
- strcat(buf,name+5);
- } else if (strcmpz(name,"bu10:")==0) {
- strcpy(buf,bu10_path);
- strcat(buf,name+5);
- } else if (strcmpz(name,"pcdrv:")==0) {
- strcpy(buf,pcdrv_path);
- strcat(buf,name+6);
- } else return NULL;
-
- return buf;
- }
-
- static int bios_open(char *name,int psxmode)
- {
- /* psx define
- #define O_RDONLY 1
- #define O_WRONLY 2
- #define O_RDWR 3
- #define O_CREAT 0x200
- */
- int mode=O_BINARY;
-
- switch(psxmode&3) {
- case 1: mode|=O_RDONLY; break;
- case 2: mode|=O_WRONLY; break;
- case 3: mode|=O_RDWR; break;
- }
- if (psxmode&0x200) mode|=O_CREAT;
-
- PRINTF("%s",name);
-
- return open(real_path(name),mode);
- }
-
- #if 0
- static void bios_setjmp(int *jmpbuf)
- {
- jmpbuf[0] = reg.r[31]; /* ra */
- jmpbuf[1] = reg.r[29]; /* sp */
- jmpbuf[2] = reg.r[28]; /* fp */
- jmpbuf[3] = reg.r[16]; /* s0 */
- jmpbuf[4] = reg.r[17]; /* s1 */
- jmpbuf[5] = reg.r[18]; /* s2 */
- jmpbuf[6] = reg.r[19]; /* s3 */
- jmpbuf[7] = reg.r[20]; /* s4 */
- jmpbuf[8] = reg.r[21]; /* s5 */
- jmpbuf[9] = reg.r[22]; /* s6 */
- jmpbuf[10] = reg.r[23]; /* s7 */
- jmpbuf[11] = reg.r[28]; /* gp */
- }
- #endif
-
- static void bios_longjmp(int *jmpbuf)
- {
- reg.r[31] = jmpbuf[0]; /* ra */
- reg.r[29] = jmpbuf[1]; /* sp */
- reg.r[28] = jmpbuf[2]; /* fp */
- reg.r[16] = jmpbuf[3]; /* s0 */
- reg.r[17] = jmpbuf[4]; /* s1 */
- reg.r[18] = jmpbuf[5]; /* s2 */
- reg.r[19] = jmpbuf[6]; /* s3 */
- reg.r[20] = jmpbuf[7]; /* s4 */
- reg.r[21] = jmpbuf[8]; /* s5 */
- reg.r[22] = jmpbuf[9]; /* s6 */
- reg.r[23] = jmpbuf[10]; /* s7 */
- reg.r[28] = jmpbuf[11]; /* gp */
- }
-
- static int match(char *s1, char *s2)
- {
- if (*s1=='.') return 0;
-
- for ( ; ; ) {
- while (*s2 == '*' || *s2 == '?') {
- if (*s2++ == '*')
- while (*s1 && toupper(*s1) != toupper(*s2)) s1++;
- else
- if (*s1 == 0) return 0;
- else s1++;
- }
- if (toupper(*s1) != toupper(*s2)) return 0;
- if (*s1 == 0 ) return 1;
- s1++; s2++;
- }
- }
-
- /* PSX struct */
- struct DIRENTRY {
- char name[20];
- INT32 attr;
- UINT32 size;
- struct DIRENTRY *next;
- INT32 head;
- char system[4];
- };
-
- static DIR *hdir;
- static char pathbuf[256/*MAXPATH*/];
- static char matchname[20],*nameptr;
-
- struct DIRENTRY* nextfile(struct DIRENTRY *dir)
- {
- struct dirent *dirent;
- struct stat statbuf;
-
- if (hdir==NULL) return NULL;
- do {
- dirent = readdir(hdir);
- if (dirent == NULL) {
- closedir(hdir);
- hdir = NULL;
- return NULL;
- }
- // printf("%s %s\n",dirent->d_name,matchname);
- } while(!match(dirent->d_name,matchname));
-
- // printf("match");
-
- strcpy(dir->name,dirent->d_name);
- strcpy(nameptr,dirent->d_name);
- stat(pathbuf,&statbuf);
- dir->size = statbuf.st_size;
-
- return dir;
- }
-
- #define PATH_DELIMITER '\\'
-
- struct DIRENTRY* firstfile(char *path,struct DIRENTRY *dir)
- {
- char *p,*matchpath;
-
- // printf("path;%s\n",path);
-
- strcpy(pathbuf,real_path(path));
- p = strrchr(pathbuf,PATH_DELIMITER);
- if (p) {
- *p=0;
- matchpath = pathbuf;
- nameptr = p+1;
- } else {
- matchpath = ".";
- nameptr = pathbuf;
- }
- strcpy(matchname,nameptr);
-
- // printf("%s %s:\n",matchpath,matchname);
-
- if (hdir) {
- closedir(hdir);
- }
- hdir = opendir(matchpath);
-
- if (hdir==NULL) return NULL;
-
- if (p) {
- *p = PATH_DELIMITER;
- }
-
- return nextfile(dir);
- }
-
- static char *padbuf1,*padbuf2;
- static int padbuf1len,padbuf2len;
- static int *padbuf;
-
- static void pad_update(void)
- {
- int pad1,pad2;
-
- pad1 = 0xFFFF; // JOY_Poll(0);
- pad2 = 0xFFFF; // JOY_Poll(1);
- if (padbuf) *padbuf = (pad1 | (pad2<<16));
- if (padbuf1) {
- padbuf1[0] = 0;
- padbuf1[1] = 0x41;
- padbuf1[2] = pad1 >> 8;
- padbuf1[3] = pad1;
-
- padbuf2[0] = 0;
- padbuf2[1] = 0x41;
- padbuf2[2] = pad2>>8;
- padbuf2[3] = pad2;
- }
- }
-
- static int bios_b0()
- {
- switch(reg.r[9]) {
- case 0x12: /* InitPAD */
- padbuf1 = realaddr(a0);
- padbuf1len = a1;
- padbuf2 = realaddr(a2);
- padbuf2len = a3;
- break;
- case 0x13: /* StartPAD */
- hw_write16(0x1f801074,hw_read16(0x1f801074)|1); /* Vsync Interrupt enable */
- SR |= 0x401; /* interrupt enable */
- break;
- case 0x14: /* StopPAD */
- break;
- case 0x15: /* PAD_init */
- padbuf = realaddr(a1);
- *padbuf = -1;
- hw_write16(0x1f801074,hw_read16(0x1f801074)|1); /* Vsync Interrupt enable */
- SR |= 0x401; /* interrupt enable */
- break;
- case 0x16: /* PAD_dr */
- break;
- case 0x17: /* ReturnFromException */
- SR = (SR & ~0xf)| ((SR>>2)&0xf);
- /* WX^ðáO¶Éß· */
- memcpy(reg.r,save_reg,sizeof(save_reg));
- PC = EPC;
- break;
- case 0x19: /* HookEntryInt */
- jmpbuf = realaddr(a0);
- break;
- case 0x32: /* open */
- v0 = bios_open(realaddr(a0),a1); break;
- case 0x33: /* lseek */
- v0 = lseek(a0,a1,a2); break;
- case 0x34: /* read */
- printf("%d %x %d",(int)a0,(int)a1,(int)a2);
- v0 = read(a0,realaddr(a1),a2); break;
- case 0x35: /* write */
- v0 = write(a0,realaddr(a1),a2); break;
- case 0x36: /* close */
- v0 = close(a0); break;
- case 0x37: /* ioctl */
- case 0x38: /* exit */
- case 0x39: /* ?? */
- case 0x3a: /* getc */
- case 0x3b: /* putc */
- return -1;
- case 0x3c: /* getchar */
- v0 = getchar(); break;
- case 0x3d: /* putchar */
- v0 = putchar(a0); break;
- case 0x3e: /* gets */
- {
- char *base = (char*)baseaddr(a0);
- char *ret = gets(base + a0);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x3f: /* puts */
- v0 = puts(realaddr(a0)); break;
- case 0x42: /* 0x42 firstfile */
- {
- int t = (int)firstfile((char *)realaddr(a0),
- (struct DIRENTRY *)realaddr(a1));
- if (t) t=a1;
- v0 = t;
- }
- break;
- case 0x43: /* 0x43 nextfile */
- {
- int t = (int)nextfile((struct DIRENTRY *)realaddr(a0));
- if (t) t=a0;
- v0 = t;
- }
- break;
- case 0x51: /* Krom2RawAdd */
- {
- void *ret = Krom2RawAdd(a0);
- v0 = PSADDR(ret,rom-0xbfc00000);
- }
- break;
- default:
- /* unsupport */
- return -1;
- }
-
- return 0;
- }
-
- static int bios_c0()
- {
- switch(reg.r[9]) {
- default:
- /* unsupport */
- return -1;
- }
- return 0;
- }
-
- static int bios_a0()
- {
- switch(reg.r[9]) {
- case 0x00: /* open */
- v0 = bios_open(realaddr(a0),a1); break;
- case 0x01: /* lseek */
- v0 = lseek(a0,a1,a2); break;
- case 0x02: /* read */
- printf("%d %x %d",(int)a0,(int)a1,(int)a2);
- v0 = read(a0,realaddr(a1),a2); break;
- case 0x03: /* write */
- v0 = write(a0,realaddr(a1),a2); break;
- case 0x04: /* close */
- v0 = close(a0); break;
-
- case 0x05: /* ioctl */
- case 0x06: /* exit */
- case 0x07: /* ?? */
- case 0x08: /* getc */
- case 0x09: /* putc */
- return -1;
-
- case 0x0a: /* todigit */
- v0 = a0-'0'; break;
- case 0x0b: /* atof */
- { union { double d; int lo,hi; } t;
- t.d = atof(realaddr(a0));
- v0 = t.lo;
- v1 = t.hi;
- }
- break;
- case 0x0c: /* strtoul */
- { char *base = baseaddr(a0);
- char *endp;
- v0 = strtoul(base+a0,&endp,a2);
- if (a1) a1 = PSADDR2(endp,base);
- }
- break;
- case 0x0d: /* strtol */
- { char *base = baseaddr(a0);
- char *endp;
- v0 = strtol(base+a0,&endp,a2);
- if (a1) a1 = PSADDR2(endp,base);
- }
- break;
- case 0x0e: /* abs */
- case 0x0f: /* labs */
- v0 = (a0>=0)?a0:-a0; break;
- case 0x10: /* atoi */
- case 0x11: /* atol */
- v0 = atoi(realaddr(a0)); break;
- case 0x12: /* atob */
- return -1;
-
- case 0x13: /* setjmp */
- { int *jmpbuf=realaddr(a0);
- jmpbuf[0] = reg.r[31]; /* ra */
- jmpbuf[1] = reg.r[29]; /* sp */
- jmpbuf[2] = reg.r[28]; /* fp */
- jmpbuf[3] = reg.r[16]; /* s0 */
- jmpbuf[4] = reg.r[17]; /* s1 */
- jmpbuf[5] = reg.r[18]; /* s2 */
- jmpbuf[6] = reg.r[19]; /* s3 */
- jmpbuf[7] = reg.r[20]; /* s4 */
- jmpbuf[8] = reg.r[21]; /* s5 */
- jmpbuf[9] = reg.r[22]; /* s6 */
- jmpbuf[10] = reg.r[23]; /* s7 */
- jmpbuf[11] = reg.r[28]; /* gp */
- }
- v0 = 0;
- break;
- case 0x14: /* longjmp */
- { int *jmpbuf=realaddr(a0);
- reg.r[31] = jmpbuf[0]; /* ra */
- reg.r[29] = jmpbuf[1]; /* sp */
- reg.r[28] = jmpbuf[2]; /* fp */
- reg.r[16] = jmpbuf[3]; /* s0 */
- reg.r[17] = jmpbuf[4]; /* s1 */
- reg.r[18] = jmpbuf[5]; /* s2 */
- reg.r[19] = jmpbuf[6]; /* s3 */
- reg.r[20] = jmpbuf[7]; /* s4 */
- reg.r[21] = jmpbuf[8]; /* s5 */
- reg.r[22] = jmpbuf[9]; /* s6 */
- reg.r[23] = jmpbuf[10]; /* s7 */
- reg.r[28] = jmpbuf[11]; /* gp */
- }
- v0 = a1;
- break;
- case 0x15: /* strcat */
- v0 = a0; strcat(realaddr(a0),realaddr(a1)); break;
- case 0x16: /* strncat */
- v0 = a0; strncat(realaddr(a0),realaddr(a1),a2); break;
- case 0x17: /* strcat */
- v0 = strcmp(realaddr(a0),realaddr(a1)); break;
- case 0x18: /* strncmp */
- v0 = strncmp(realaddr(a0),realaddr(a1),a2); break;
- case 0x19: /* strcpy */
- v0 = a0; strcpy(realaddr(a0),realaddr(a1)); break;
- case 0x1a: /* strncpy */
- v0 = a0; strncpy(realaddr(a0),realaddr(a1),a2); break;
- case 0x1b: /* strlen */
- v0 = strlen(realaddr(a0)); break;
- case 0x1c: /* index */
- case 0x1e: /* strchr */
- { char *base = baseaddr(a0);
- char *ret = strchr(base + a0,a1);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x1d: /* rindex */
- case 0x1f: /* strrchr */
- { char *base = baseaddr(a0);
- char *ret = strrchr(base + a0,a1);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x20: /* strpbrk */
- { char *base = baseaddr(a0);
- char *ret = strpbrk(base + a0,realaddr(a1));
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x21: /* strspn */
- v0 = strspn(realaddr(a0),realaddr(a1)); break;
- case 0x22: /* strcspn */
- v0 = strcspn(realaddr(a0),realaddr(a1)); break;
- case 0x23: /* strtok */
- { char *base = baseaddr(a0);
- char *ret = strtok(base + a0,a1?realaddr(a1):(char*)a1);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x24: /* strstr */
- { char *base = baseaddr(a0);
- char *ret = strstr(base + a0,realaddr(a1));
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x25: /* toupper */
- v0 = toupper(a0); break;
- case 0x26: /* tolower */
- v0 = tolower(a0); break;
- case 0x27: /* bcopy */
- memcpy(realaddr(a1),realaddr(a0),a2); break;
- case 0x28: /* bzero */
- memset(realaddr(a0),0,a1); break;
- case 0x29: /* bcmp */
- v0 = memcmp(realaddr(a0),realaddr(a1),a2); break;
- case 0x2a: /* memcpy */
- v0 = a0; memcpy(realaddr(a0),realaddr(a1),a2); break;
- case 0x2b: /* memset */
- v0 = a0; memset(realaddr(a0),a1,a2); break;
- case 0x2c: /* memmove */
- v0 = a0; memmove(realaddr(a0),realaddr(a1),a2); break;
- case 0x2d: /* memcmp */
- v0 = memcmp(realaddr(a0),realaddr(a1),a2); break;
- case 0x2e: /* memchr */
- { char *base = baseaddr(a0);
- char *ret = memchr(base + a0,a1,a2);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x2f: /* rand */
- v0 = rand(); break;
- case 0x30: /* srand */
- srand(a0); break;
- case 0x31: /* qsort */
- qbase = baseaddr(a0);
- qsub = a3;
- qsort(qbase + a0,a1,a2,qcmp);
- break;
- case 0x32: /* strtod */
- { char *base = baseaddr(a0);
- char *endp;
- union { double d; int lo,hi; } t;
- t.d = strtod(base+a0,&endp);
- v0 = t.lo;
- v1 = t.hi;
- if (a1) a1 = PSADDR2(endp,base);
- }
- break;
- case 0x33: /* malloc */
- {
- char *ret = bios_malloc(a0);
- v0 = PSADDR(ret,heapbase);
- }
- break;
- case 0x34: /* free */
- bios_free(PCADDR(a0,heapbase));
- break;
- case 0x35: /* lsearch */
- return -1;
- /*
- qbase = baseaddr(a0);
- qsub = stack[4];
- {
- char *ret = lsearch(qbase+a0,qbase+a1,realaddr(a2),a3,qcmp);
- v0 = PSADDR(ret,qbase);
- }
- break;
- */
- case 0x36: /* bsearch */
- qbase = baseaddr(a0);
- qsub = stack[4];
- {
- char *ret = bsearch(qbase+a0,qbase+a1,a2,a3,qcmp);
- v0 = PSADDR(ret,qbase);
- }
- break;
- case 0x37: /* calloc */
- {
- char *ret = bios_calloc(a0,a1);
- v0 = PSADDR(ret,heapbase);
- }
- break;
- case 0x38: /* realloc */
- {
- char *ret = bios_realloc(PCADDR(a0,heapbase),a1);
- v0 = PSADDR(ret,heapbase);
- }
- break;
- case 0x39: /* InitHeap */
- heapbase = baseaddr(a0);
- bios_InitHeap(heapbase + a0,a1);
- break;
- case 0x3a: /* _exit */
- return -1;
- case 0x3b: /* getchar */
- v0 = getchar(); break;
- case 0x3c: /* putchar */
- v0 = putchar(a0); break;
- case 0x3d: /* gets */
- { char *base = (char*)baseaddr(a0);
- char *ret = gets(base + a0);
- v0 = PSADDR(ret,base);
- }
- break;
- case 0x3e: /* puts */
- v0 = puts(realaddr(a0)); break;
- case 0x3f: /* printf */
- /* ¼ */
- {char *s = realaddr(a0);
-
- // if (strstr(s,"%s")) {
- // v0 = printf("%s",s);
- // } else {
-
- long *ptr = realaddr(sp);
- ptr[1] = a1;
- ptr[2] = a2;
- ptr[3] = a3;
- #ifdef __WATCOMC__
- v0 = vprintf(s,(char*)(ptr+1));
- #else
- v0 = vprintf(s,*((va_list*)(ptr+1)));
- #endif
- // }
- }
- break;
-
- case 0x46: /* GPU_dw */
- {
- int size;
- long *ptr;
- GP0_Write(0xa0000000);
- GP0_Write((a1<<16)|(a0&0xffff));
- GP0_Write((a3<<16)|(a2&0xffff));
- size = (a2*a3+1)/2;
- ptr = realaddr(stack[4]);
- do {
- GP0_Write(*ptr++);
- } while(--size);
- }
- break;
- case 0x47: /* mem2vram */
- {
- int size;
- PRINTF("%d %d %d %d %x",(int)a0,(int)a1,(int)a2,(int)a3,(int)stack[4]);
- GP0_Write(0xa0000000);
- GP0_Write((a1<<16)|(a0&0xffff));
- GP0_Write((a3<<16)|(a2&0xffff));
- size = (a2*a3+1)/2;
- GP1_Write(0x04000002);
- hw_write32(0x1f8010f4,0);
- hw_write32(0x1f8010f0,hw_read32(0x1f8010f0)|0x800);
- hw_write32(0x1f8010a0,stack[4]);
- hw_write32(0x1f8010a4,((size/16)<<16)|16);
- hw_write32(0x1f8010a8,0x01000201);
- }
- break;
- case 0x48: /* SendGPU */
- GP1_Write(a0);
- break;
- case 0x49: /* GPU_cw */
- GP0_Write(a0);
- break;
- case 0x4a: /* GPU_cwb */
- {
- long *ptr = realaddr(a0);
- int size = a1;
- while(size--) {
- GP0_Write(*ptr++);
- }
- }
- break;
- case 0x4b: /* SendPackets */
- GP1_Write(0x04000002);
- hw_write32(0x1f8010f4,0);
- hw_write32(0x1f8010f0,hw_read32(0x1f8010f0)|0x800);
- hw_write32(0x1f8010a0,a0);
- hw_write32(0x1f8010a4,0);
- hw_write32(0x1f8010a8,0x010000401);
- break;
- case 0x4c: /* ??? */
- hw_write32(0x1f8010a8,0x00000401);
- GP0_Write(0x0400000);
- GP0_Write(0x0200000);
- GP0_Write(0x0100000);
- break;
- case 0x4d: /* GetGPUStatus */
- v0 = GP1_Read();
- break;
- case 0x4e: /* GPU_sync */
- break;
- default:
- /* unsupport */
- return -1;
- }
- return 0;
- }
-
- #if 0
- int bios_printf(char *fmt,int *arg)
- {
- int ch;
- static char decimal = '.';
-
- for(cnt=0;;) {
- while((ch = *fmt++) && ch!='%') { putchar(ch); cnt++; }
- if (ch=='\0') break;
- rflag:
- switch(*fmt++) {
- case ' ': if (!sign) sign=' '; goto rflag;
- case '#': flags |= ALT; goto rflag;
- case '*':
- case '-': flags |= LADJUST; goto rflag;
- case '+': sign = '+'; goto rflag;
- case '.': if (*fmt=='*') {}
- case '0':
- case '1':case '2':case '3':case '4':
- case '5':case '6':case '7':case '8':case '9':
- case 'L': flags |= LONGDBL; goto rflag;
- case 'h': flags |= SHORTINT; goto rflag;
- case 'l': if (flags&LONGINT) flags |= LONGDBL; else flags = LONGINT;
- goto rflag;
- case 'q':
- case 'c':
- case 'D': flags |= LONGINT;
- case 'd':
- case 'i':
- case 'E':
- case 'e':
- case 'f':
- case 'g':
- case 'G':
- case 'n':
- case 'O':
- case 'o':
- case 'p':
- case 's':
- case 'U': flags |= LONGINT;
- case 'u':
- case 'X':
- case 'x':
-
- }
- }
- }
- #endif
-
- int interrupt_handler()
- {
- int intr;
-
- intr = hw_read16(0x1f801070) & hw_read16(0x1f801074); /* int reg & mask */
- if (intr&1) { /* VSync interrupt */
- pad_update();
- }
- hw_write16(0x1f801070,0);
- hw_write32(0x1F8010F4,hw_read32(0x1F8010F4));
- return 0;
- }
-
- int exception_handler()
- {
- if (!emulate_bios) return 0;
- switch((CAUSE&0x3c)>>2) {
- case E_Int:
- /* WX^Û¶ */
- memcpy(save_reg,reg.r,sizeof(save_reg));
- if (jmpbuf) {
- /* HookEntryIntÌÝèɧäªÚé */
- bios_longjmp(jmpbuf);
- v0 = 1;
- PC = reg.r[31];
- hw_write32(0x1f801070,0xFFFFFFFF);
- } else {
- interrupt_handler();
- PC = EPC;
- SR = (SR & ~0xf)| ((SR>>2)&0xf); /* rfe */
- }
- break;
- case E_Sys:
- switch(reg.r[4]) {
- case 1: SR &= ~0x404; PC = EPC+4; break;
- case 2: SR |= 0x404; PC = EPC+4; break;
- default: return -1;
- }
- SR = (SR & ~0xf)| ((SR>>2)&0xf); /* rfe */
- break;
- default:
- return -1;
- }
-
- return 0;
- }
-
- /*
- FONTX format
-
- idx siz
- 0 6 id "FONTX"
- 6 8 name
- 14 1 width
- 15 1 height
- 16 1 type (0=ANK 1=Japanese)
- ANK:
- 17 font data (0x00-0xff)
-
- Japanese:
- 17 1 Number of code table
- 18 2 start of code
- 20 2 end of code
- .
- .
- 18+N*4 font data
- */
-
- void *fileload(char *file,void *buf)
- {
- FILE *fp;
- int fsize;
-
- fp = fopen(file,"rb");
- if (fp==NULL) return NULL;
- fseek(fp,0,SEEK_END);
- fsize = ftell(fp);
- fseek(fp,0,SEEK_SET);
- if (buf!=NULL || (buf = malloc(fsize))!=NULL) {
- fread(buf,1,fsize,fp);
- }
- fclose(fp);
- return buf;
- }
-
- static char *fontfile = "JPNZN16X.X11";
-
- int bios_init(void)
- {
- /* font load at rom area */
- font = (void*)(rom+0x20000);
- fileload(fontfile,font);
- return 0;
- }